package logic

import (
	"context"
	"encoding/json"
	"fmt"
	"order/global/model"
	"order/global/pkg"
	"time"

	"order/internal/svc"
	"order/order"

	"github.com/zeromicro/go-zero/core/logx"
)

type OrderBuildLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewOrderBuildLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderBuildLogic {
	return &OrderBuildLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *OrderBuildLogic) OrderBuild(in *order.OrderBuildRequest) (*order.OrderBuildResponse, error) {
	// todo: add your logic here and delete this line
	if in.IsSeckill == 0 {
		var key = fmt.Sprintf("product:%d", in.GoodsId)
		result, err := model.RDB.Get(model.Ctx, key).Result()
		if err != nil {
			return nil, fmt.Errorf("商品已下架")
		}
		var product model.Product
		json.Unmarshal([]byte(result), &product)
		if int32(in.GoodsNumber) > product.Stock {
			return nil, fmt.Errorf("库存不足")
		}
		var orders = model.Order{
			UserId:      int32(in.UserId),
			ProductId:   int32(in.GoodsId),
			OrderType:   fmt.Sprintf("%d", in.IsSeckill),
			Amount:      product.Price * float32(in.GoodsNumber),
			OrderStatus: "0",
			CreateTime:  time.Now(),
		}
		beg := model.DB.Begin()
		if err = beg.Create(&orders).Error; err != nil {
			beg.Rollback()
			return nil, err
		}
		product.Stock -= int32(in.GoodsNumber)
		if err = beg.Model(&model.Product{}).Where("product_id = ?", product.ProductId).Updates(&product).Error; err != nil {
			beg.Rollback()
			return nil, err
		}
		data, _ := json.Marshal(product)
		if err = model.RDB.Set(model.Ctx, key, data, 0).Err(); err != nil {
			beg.Rollback()
			return nil, err
		}
		beg.Commit()
		url := pkg.AliPay(orders)
		return &order.OrderBuildResponse{
			Url: url,
		}, nil
	} else {
		once := fmt.Sprintf("%d:%d", in.UserId, in.GoodsId)
		ok := model.RDB.Exists(model.Ctx, once).Val()
		if ok != 0 {
			return nil, fmt.Errorf("已经抢购过了")
		}
		var key = fmt.Sprintf("product:seckill:%d", in.GoodsId)
		result, err := model.RDB.Get(model.Ctx, key).Result()
		if err != nil {
			return nil, fmt.Errorf("活动已结束")
		}
		var sec model.Seckill
		json.Unmarshal([]byte(result), &sec)
		if int(in.GoodsNumber) > sec.SeckillStock {
			return nil, fmt.Errorf("库存不足")
		}
		var orders = model.Order{
			UserId:      int32(in.UserId),
			ProductId:   int32(in.GoodsId),
			OrderType:   fmt.Sprintf("%d", in.IsSeckill),
			Amount:      float32(sec.SeckillPrice * int(in.GoodsNumber)),
			OrderStatus: "1",
			CreateTime:  time.Now(),
		}
		beg := model.DB.Begin()
		if err = beg.Create(&orders).Error; err != nil {
			beg.Rollback()
			return nil, err
		}
		sec.SeckillStock -= int(in.GoodsNumber)
		data, _ := json.Marshal(sec)
		if err = model.RDB.Set(model.Ctx, key, data, 0).Err(); err != nil {
			beg.Rollback()
			return nil, err
		}
		url := pkg.AliPay(orders)

		model.RDB.Set(model.Ctx, once, "ok", 0)
		return &order.OrderBuildResponse{
			Url: url,
		}, nil
	}
}
